home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
-
- #include "symbol.h"
- #include "code.h"
- #include "math.tab.h"
- #include "fudgit.h"
- #include "head.h"
-
- #define LQUOTE '"'
- #define ANY (-1)
- extern int Ft_Samples;
- extern int Ft_Debug;
-
- char Ft_Puffer[MAXMACRO+8];
-
- static char *Pp;
- static int follow(char expect, int ifyes, int ifno);
-
-
- extern int Ft_autosymremove (int level);
- extern void Ft_matherror (char *s1, char *s2, int lino);
- extern int Ft_mathyyparse (void);
- int Ft_varcpy (char *to, char *from);
- extern int Ft_iolevel (void);
- extern int Ft_almost (register char *str1, register char *str2);
-
- void Ft_initmathyylex(char *str)
- {
- strcpy(Ft_Puffer, str);
- Pp = Ft_Puffer;
- if (Ft_Debug & DEBUG_MATH)
- fputs(Pp, stderr);
- }
-
- int Ft_mathyyerror(char *str)
- {
- extern int Ft_mathyystate;
- extern int Ft_mathyychar;
-
- Ft_autosymremove(0);
- #ifdef YYDEBUG
- fprintf(stderr, "Cmode parser: %s. (token `%c`; current state %d)\n",
- str, Ft_mathyychar, Ft_mathyystate);
- Ft_catcher(ERRR);
- #else
- Ft_matherror("Cmode parser: %s.", str, 0);
- #endif
- return(ERRR); /* DUMMY */
- }
-
- int Ft_mathyylex(void)
- {
- int c;
- extern int Ft_iolevel(void);
- extern int Ft_Inproto, Ft_Indef, Ft_Inauto, Ft_Inbrace;
-
- while (*Pp == ' ' || *Pp == '\t') /* remove space if any */
- Pp++;
- if (*Pp == 0)
- return(0);
- c = *Pp;
- if (c == '.' || isdigit(c)) { /* a number */
- double d;
- if (sscanf(Pp, "%lf", &d) != 1) {
- Ft_matherror("Wierd number near... %s", Pp, 0);
- }
- while (c == '.' || isdigit(c))
- c = *++Pp;
- if (c == 'e' || c == 'E') {
- c = *++Pp;
- if (c == '-')
- c = *++Pp;
- while (isdigit(c))
- c = *++Pp;
- }
- Ft_mathyylval.val = d;
- return(NUMBER);
- }
- else if (c == LQUOTE) { /* a string */
- char strbuf[TOKENSIZE+1];
- char *p;
-
- c = *++Pp;
- p = strbuf;
- while (c != LQUOTE) {
- if (c == '\n' || c == '\0') {
- fprintf(stderr, "Math error: Unmatched quote %c.\n", LQUOTE);
- Ft_catcher(ERRR);
- }
- if ((p - strbuf) >= TOKENSIZE) {
- *p = '\0';
- Ft_matherror("%s: String too long.", strbuf, 0);
- }
- if (c == '\\') {
- #ifdef NOALERTCHAR
- static char transtab[] = "b\bf\fn\nr\rt\tv\v";
- #else
- static char transtab[] = "b\bf\fn\nr\rt\ta\av\v";
- #endif
- char *ch;
- extern char *strchr(const char *, int);
-
- c = *++Pp;
- if (islower(c) && (ch = strchr(transtab, c))) {
- *p++ = ch[1];
- }
- else { /* put next char as is */
- *p++ = c;
- }
- c = *++Pp;
- continue;
- }
- *p++ = c;
- c = *++Pp;
- }
- *p = '\0';
- Pp++; /* swallow last quote */
- Ft_mathyylval.sym = Ft_install("", STRING, strlen(strbuf));
- strcpy(Ft_mathyylval.sym->u.str, strbuf);
- return(STRING);
- }
- else if (isalpha(c)) { /* a function or a variable */
- char vname[TOKENSIZE+1];
- Symbol *s;
- int type, argno;
-
- type = Ft_varcpy(vname, Pp);
- Pp += strlen(vname);
- if (Ft_Inproto) {
- if (Ft_autolookup(vname, ANY))
- Ft_matherror("%s: Repeated argument name.", vname, 0);
- switch (type) {
- case VAR:
- Ft_autoinstall(vname, ARG, 0);
- return(VARARG);
- case STRVAR:
- Ft_autoinstall(vname, ARG, 0);
- return(STRVARARG);
- case VEC:
- Ft_autoinstall(vname, ARG, 0);
- if (Ft_almost(vname, "P!ARAM"))
- return(PARARG);
- return(VECARG);
- default:
- Ft_matherror("%s: Impossible case in lexi!", vname, 0);
- }
- }
- if (Ft_Inauto) {
- if (Ft_Indef && Ft_autolookup(vname, 0))
- Ft_matherror("%s: Already defined as a prototype.", vname, 0);
- switch (type) {
- case VAR:
- Ft_autoinstall(vname, AUTO, Ft_Inbrace);
- return(VARARG);
- case STRVAR:
- Ft_autoinstall(vname, AUTO, Ft_Inbrace);
- return(STRVARARG);
- case VEC:
- Ft_autoinstall(vname, AUTO, Ft_Inbrace);
- return(VECARG);
- default:
- Ft_matherror("%s: Impossible case in lexi!", vname, 0);
- }
- }
- if ((argno = Ft_autolookup(vname, ANY))) {
- Ft_mathyylval.narg = argno;
- switch (type) {
- case STRVAR: return(STRVARARG);
- case VAR: return(VARARG);
- case VEC: if (Ft_almost(vname, "P!ARAM"))
- return(PARARG);
- return(VECARG);
- default:
- Ft_matherror("%s: Impossible case in lexi!", vname, 0);
- }
- }
- if ((s = Ft_lookup(vname)) == 0) {
- switch (type) {
- case STRVAR:
- s = Ft_install(vname, UNDEFSTRVAR, 0);
- break;
- case VAR:
- s = Ft_install(vname, UNDEFVAR, 1);
- break;
- case VEC:
- s = Ft_install(vname, UNDEFVEC, Ft_Samples);
- break;
- default:
- Ft_matherror("%s: Impossible case in lexi!", vname, 0);
- }
- }
- Ft_mathyylval.sym = s;
- switch(s->type) {
- case UNDEFVAR: return(VAR);
- case UNDEFVEC: return(VEC);
- case UNDEFSTRVAR: return(STRVAR);
- case BLTINVAR: return(VAR);
- case BLTINSTRVAR: return(STRVAR);
- case BLTINCONST: return(CONST);
- case BLTINSTRCONST: return(STRCONST);
- default: return(s->type);
- }
- }
- Pp++;
- switch (c) {
- case '+':
- if(follow('+', INCR, '+') == '+')
- return(follow('=', ADDASS, '+'));
- else
- return(INCR);
- case '-':
- if(follow('-', DECR, '-') == '-')
- return(follow('=', SUBASS, '-'));
- else
- return(DECR);
- case '/': return(follow('=', DIVASS, '/'));
- case '*': return(follow('=', MULASS, '*'));
- case '>': return(follow('=', GE, GT));
- case '<': return(follow('=', LE, LT));
- case '=': return(follow('=', EQ, '='));
- case '!': return(follow('=', NE, NOT));
- case '|': return(follow('|', OR, '|'));
- case '&': return(follow('&', AND, '&'));
- default: return(c);
- }
- }
-
- static int follow(char expect, int ifyes, int ifno)
- {
- if (*Pp == expect) {
- Pp++;
- return(ifyes);
- }
- return(ifno);
- }
-
- int Ft_more_input(int level, char *iprompt)
- {
- int eof;
- char *cp;
- char prompt[128];
- char *cpt;
- extern char *Ft_expandedline(char *prompt, int type, int *eof);
- extern char Ft_Prompt_cm[];
- extern int Ft_Interact;
-
- cpt = prompt;
- if (Ft_Interact && !Ft_iolevel()) { /* Do we build a prompt ? */
- int i = level;
-
- if (level>0) {
- cp = cpt;
- while (i) {
- *cp = '{';
- cp++; i--;
- }
- if (iprompt) {
- int len = strlen(iprompt);
-
- strcpy(cp, iprompt);
- cp += len;
- }
- strcpy(cp, "... ");
- cp += 7;
- for (i=level;i;i--,cp+=4)
- strcpy(cp, " ");
- }
- else if (iprompt) {
- cpt = iprompt;
- }
- else {
- cpt = Ft_Prompt_cm;
- }
- }
- else {
- *prompt = '\0';
- }
- if ((cp = Ft_expandedline(cpt, EXPANSION | PARENTH, &eof)) == NULL) {
- if (eof) {
- if (eof > 0) /* not a ^D */
- fputs("Warning: Eof or Eom occurred while still in cmode.\n",
- stderr);
- return(0);
- }
- Ft_initmathyylex("\n"); /* forgive newlines in statements */
- return(ERRR); /* this means to continue */
- }
- if (Ft_almost(cp, "fm!ode") || Ft_almost(cp, "quit")) {
- return(0);
- }
- else if (Ft_almost(cp, "cm!ode")) {
- fputs("Warning: cmode: Program already in C mode: Line ignored.\n",
- stderr);
- return(ERRR); /* We want to continue */
- }
- Ft_initmathyylex(cp);
- return(1);
- }
-
- #define isacceptable(c) ((c) == '_')
-
- int Ft_varcpy(char *to, char *from)
- {
- int up = 0;
- int alf = 0;
- int c = *from;
- int i = 0;
- char *save = to;
-
- if (!to)
- to = from;
- do { /* copy variable name */
- if (!isdigit(c) && !isacceptable(c)) {
- up += (isupper(c) != 0);
- alf++;
- }
- *to++ = *from;
- c = *++from;
- if (++i >= TOKENSIZE) {
- *to = '\0';
- Ft_matherror("%s: Variable name too long!", save, 0);
- }
- } while (c && (isalnum(c) || isacceptable(c)));
- *to = '\0';
- if (up != 0 && up != alf) /* not all lower-upper case */
- return(STRVAR);
- if (up == 0) /* All lower case => variable or function */
- return(VAR);
- return(VEC);
- }
-
- void Ft_mathuser(void) /* mostly non-linear */
- {
- extern char Ft_UFunction[];
-
- Ft_initcode();
- Ft_initmathyylex(Ft_UFunction);
- for (;*Pp;Ft_initcode())
- Ft_mathyyparse();
-
- return;
- }
-